package httprouter

import (
	"log"
	"net/http"
	"os"
	"path/filepath"
	"runtime"
	"strings"
	"time"

	"dnslog/config"
	"dnslog/core"

	"github.com/gin-gonic/gin"
)

type Router struct {
	platform    *core.DNSLogPlatform
	config      *config.Config
	adminEngine *gin.Engine
	frontEngine *gin.Engine
	projectRoot string
}

// NewRouter 创建新的路由器
func NewRouter(platform *core.DNSLogPlatform, cfg *config.Config) *Router {
	router := &Router{
		platform:    platform,
		config:      cfg,
		adminEngine: gin.Default(),
		frontEngine: gin.Default(),
		projectRoot: getProjectRoot(),
	}

	router.setupAdminRoutes()
	router.setupFrontRoutes()
	return router
}

// getProjectRoot 获取项目根目录
func getProjectRoot() string {
	_, filename, _, _ := runtime.Caller(0)
	projectRoot := filepath.Dir(filepath.Dir(filename))

	if _, err := os.Stat(filepath.Join(projectRoot, "templates")); os.IsNotExist(err) {
		wd, err := os.Getwd()
		if err == nil {
			if filepath.Base(wd) == "cmd" {
				projectRoot = filepath.Dir(wd)
			} else {
				projectRoot = wd
			}
		}
	}

	return projectRoot
}

// authMiddleware 认证中间件
func (r *Router) authMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		if !r.config.Auth.Enabled {
			c.Next()
			return
		}

		// 检查会话
		token, err := c.Cookie("auth_token")
		if err != nil || !r.isValidToken(token) {
			// 如果是API请求，返回JSON错误
			if strings.HasPrefix(c.Request.URL.Path, "/api/") {
				c.JSON(http.StatusUnauthorized, gin.H{
					"success": false,
					"error":   "认证失败",
				})
				c.Abort()
				return
			}

			// 否则重定向到登录页面
			c.Redirect(http.StatusFound, "/login")
			c.Abort()
			return
		}

		c.Next()
	}
}

// isValidToken 验证token有效性（简化实现）
func (r *Router) isValidToken(token string) bool {
	// 这里可以扩展为更复杂的token验证逻辑
	// 目前简单实现为检查token是否在有效列表中
	return token == "admin_session" // 简化实现，实际应该使用JWT或其他机制
}

// setupAdminRoutes 设置后台管理路由
func (r *Router) setupAdminRoutes() {
	log.Printf("📁 Setting up admin routes on port %d", r.config.Server.Admin.Port)

	// 静态文件 - 使用项目根目录的绝对路径
	staticPath := filepath.Join(r.projectRoot, "static")
	r.adminEngine.Static("/static", staticPath)

	// 模板路径
	templatesPath := filepath.Join(r.projectRoot, "templates", "*.html")
	r.adminEngine.LoadHTMLGlob(templatesPath)

	// 登录页面
	r.adminEngine.GET("/login", func(c *gin.Context) {
		c.HTML(http.StatusOK, "login.html", gin.H{
			"Domain": r.platform.GetDomain(),
		})
	})

	// 认证API
	r.adminEngine.POST("/api/auth/login", func(c *gin.Context) {
		var loginReq struct {
			Username string `json:"username"`
			Password string `json:"password"`
		}

		if err := c.ShouldBindJSON(&loginReq); err != nil {
			c.JSON(http.StatusBadRequest, gin.H{
				"success": false,
				"error":   "无效的请求数据",
			})
			return
		}

		if r.config.ValidateUser(loginReq.Username, loginReq.Password) {
			// 设置认证cookie（简化实现）
			c.SetCookie("auth_token", "admin_session", 3600, "/", "", false, true)
			log.Printf("✅ 用户登录成功: %s", loginReq.Username)

			c.JSON(http.StatusOK, gin.H{
				"success": true,
				"message": "登录成功",
				"user": gin.H{
					"username": loginReq.Username,
					"role":     r.config.GetUserRole(loginReq.Username),
				},
			})
		} else {
			log.Printf("❌ 登录失败: %s", loginReq.Username)
			c.JSON(http.StatusUnauthorized, gin.H{
				"success": false,
				"error":   "用户名或密码错误",
			})
		}
	})

	// 登出API
	r.adminEngine.POST("/api/auth/logout", func(c *gin.Context) {
		c.SetCookie("auth_token", "", -1, "/", "", false, true)
		c.JSON(http.StatusOK, gin.H{
			"success": true,
			"message": "登出成功",
		})
	})

	// 受保护的路由组
	protected := r.adminEngine.Group("/")
	protected.Use(r.authMiddleware())

	// 后台管理首页
	protected.GET("/", func(c *gin.Context) {
		userToken := c.Query("token")
		log.Printf("🌐 Admin homepage accessed with token: %s", userToken)

		if userToken == "" {
			// 生成新token和子域名
			newToken, err := r.platform.GenerateRandomToken()
			if err != nil {
				c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to generate token"})
				return
			}
			newSubdomain := r.platform.GenerateSubdomain(newToken)
			log.Printf("🆕 New user generated - Token: %s, Subdomain: %s", newToken, newSubdomain)
			c.Redirect(http.StatusFound, "/?token="+newToken)
			return
		}

		// 如果用户已存在，确保有子域名
		subdomain := r.platform.GetUserSubdomain(userToken)
		if subdomain == "" {
			// 如果用户token存在但没有子域名，生成一个
			subdomain = r.platform.GenerateSubdomain(userToken)
			log.Printf("🔄 Regenerated subdomain for existing token - Token: %s, Subdomain: %s", userToken, subdomain)
		}

		records := r.platform.GetDNSRecords(userToken)

		log.Printf("📋 Rendering admin page - Token: %s, Subdomain: %s, Records count: %d",
			userToken, subdomain, len(records))

		c.HTML(http.StatusOK, "index.html", gin.H{
			"Token":     userToken,
			"Subdomain": subdomain,
			"Records":   records,
			"Domain":    r.platform.GetDomain(),
		})
	})

	// API: 获取DNS记录
	protected.GET("/api/records", func(c *gin.Context) {
		userToken := c.Query("token")
		log.Printf("📡 Admin API records request - Token: %s", userToken)

		if userToken == "" {
			log.Printf("❌ Admin API records: Token required")
			c.JSON(http.StatusBadRequest, gin.H{"error": "Token required"})
			return
		}

		records := r.platform.GetDNSRecords(userToken)
		log.Printf("📊 Admin API records response - Token: %s, Records count: %d", userToken, len(records))

		c.JSON(http.StatusOK, gin.H{
			"success": true,
			"data":    records,
			"debug": gin.H{
				"token":     userToken,
				"subdomain": r.platform.GetUserSubdomain(userToken),
				"count":     len(records),
			},
		})
	})

	// API: 生成新的子域名
	protected.POST("/api/refresh", func(c *gin.Context) {
		userToken := c.Query("token")
		if userToken == "" {
			c.JSON(http.StatusBadRequest, gin.H{"error": "Token required"})
			return
		}

		// 先清空该用户旧的记录
		oldSubdomain := r.platform.GetUserSubdomain(userToken)
		if oldSubdomain != "" {
			r.platform.ClearDNSRecords(userToken)
			log.Printf("🗑️ Cleared old records for: %s", oldSubdomain)
		}

		// 生成新的子域名
		newSubdomain := r.platform.GenerateSubdomain(userToken)
		log.Printf("🔄 Refreshed subdomain - Token: %s, Old: %s, New: %s",
			userToken, oldSubdomain, newSubdomain)

		c.JSON(http.StatusOK, gin.H{
			"success":   true,
			"subdomain": newSubdomain,
		})
	})

	// API: 清空记录
	protected.POST("/api/clear", func(c *gin.Context) {
		userToken := c.Query("token")
		if userToken == "" {
			c.JSON(http.StatusBadRequest, gin.H{"error": "Token required"})
			return
		}

		r.platform.ClearDNSRecords(userToken)
		c.JSON(http.StatusOK, gin.H{
			"success": true,
		})
	})
}

// setupFrontRoutes 设置前台路由
func (r *Router) setupFrontRoutes() {
	log.Printf("📁 Setting up front routes on port %d", r.config.Server.Front.Port)

	// 前台主要用于接收DNS查询的HTTP请求
	r.frontEngine.Use(func(c *gin.Context) {
		host := c.Request.Host
		sourceIP := c.ClientIP()
		method := c.Request.Method
		path := c.Request.URL.Path

		// 记录所有 HTTP 请求
		log.Printf("🌐 Front HTTP Request: %s %s%s from %s, Host: %s",
			method, host, path, sourceIP, host)

		// 如果请求的是我们的域名，记录到 DNSLOG
		if strings.Contains(host, r.platform.GetDomain()) {
			r.platform.AddDNSRecord(host, sourceIP, "HTTP")
			log.Printf("💾 Recorded HTTP request: %s", host)
		}

		c.Next()
	})

	// 前台默认返回简单响应
	r.frontEngine.Any("/*path", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "DNSLOG Platform",
			"domain":  r.platform.GetDomain(),
			"time":    time.Now().Format(time.RFC3339),
		})
	})
}

// Start 启动HTTP/HTTPS服务器
func (r *Router) Start() error {
	// 启动前台服务器（HTTP）
	go func() {
		frontAddr := r.config.GetFrontAddr()
		log.Printf("🌐 Front HTTP server starting on http://%s", frontAddr)
		if err := r.frontEngine.Run(frontAddr); err != nil {
			log.Fatalf("Failed to start front server: %v", err)
		}
	}()

	// 启动后台管理服务器（HTTP 或 HTTPS）
	adminAddr := r.config.GetAdminAddr()

	if r.config.Server.SSL.Enabled {
		// 启动 HTTPS 服务器
		certFile := r.getAbsolutePath(r.config.Server.SSL.CertPath)
		keyFile := r.getAbsolutePath(r.config.Server.SSL.KeyPath)

		// 检查证书文件是否存在
		if _, err := os.Stat(certFile); os.IsNotExist(err) {
			log.Fatalf("❌ SSL 证书文件不存在: %s", certFile)
		}
		if _, err := os.Stat(keyFile); os.IsNotExist(err) {
			log.Fatalf("❌ SSL 私钥文件不存在: %s", keyFile)
		}

		log.Printf("🔒 Admin HTTPS server starting on https://%s", adminAddr)
		log.Printf("   Certificate: %s", certFile)
		log.Printf("   Private Key: %s", keyFile)

		return r.adminEngine.RunTLS(adminAddr, certFile, keyFile)
	} else {
		// 启动 HTTP 服务器
		log.Printf("🔧 Admin HTTP server starting on http://%s", adminAddr)
		return r.adminEngine.Run(adminAddr)
	}
}

// getAbsolutePath 获取文件的绝对路径
func (r *Router) getAbsolutePath(relativePath string) string {
	if filepath.IsAbs(relativePath) {
		return relativePath
	}
	return filepath.Join(r.projectRoot, relativePath)
}

// GetDomain 获取域名
func (r *Router) GetDomain() string {
	return r.platform.GetDomain()
}
